//-----------------------------------------------------------------------------
// File: DrawHelpers.cs
//
// Copyright (c) Dmitry Shuklin. All rights reserved.
//-----------------------------------------------------------------------------
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace ObjectiveDraw.Platform
{


	public class ToolBarDrawHelper
	{

		private ToolBarDrawHelper()
		{
		}

		public static void RenderToolBack(object sender, Cerebrum.Direct3D.Forms.RenderEventArgs e)
		{
			Cerebrum.Direct3D.Forms.Control control = sender as Cerebrum.Direct3D.Forms.Control;
			
			ObjectiveDraw.Platform.GraphChartDevice dev = control.FindDevice() as ObjectiveDraw.Platform.GraphChartDevice;
			Color clr = dev.ToolbarSeparatorBorderColor;

			System.Drawing.PointF p1, p2;
			System.Drawing.RectangleF rect = control.SurfaceRectangle;
			switch(control.Dock)
			{
				case System.Windows.Forms.DockStyle.Left:
					p1 = new System.Drawing.PointF(rect.Right-1, rect.Top);
					p2 = new System.Drawing.PointF(rect.Right-1, rect.Bottom-1);
					break;
				case System.Windows.Forms.DockStyle.Right:
					p1 = new System.Drawing.PointF(rect.Left, rect.Top);
					p2 = new System.Drawing.PointF(rect.Left, rect.Bottom-1);
					break;
				case System.Windows.Forms.DockStyle.Top:
					p1 = new System.Drawing.PointF(rect.Left, rect.Top);
					p2 = new System.Drawing.PointF(rect.Right-1, rect.Top);
					break;
				case System.Windows.Forms.DockStyle.Bottom:
					p1 = new System.Drawing.PointF(rect.Left, rect.Bottom-1);
					p2 = new System.Drawing.PointF(rect.Right-1, rect.Bottom-1);
					break;
				default:
					p1 = rect.Location;
					p2 = new System.Drawing.PointF(rect.Right, rect.Bottom);
					break;
			}

			Cerebrum.Direct3D.Drawing.Graphics _Graphics = Cerebrum.Direct3D.Drawing.Graphics.FromDevice(e.Device);
			_Graphics.DrawLine(p1, p2, control.Z, clr, clr);
		}

		public static void RenderBandBack(object sender, Cerebrum.Direct3D.Forms.RenderEventArgs e)
		{
			Cerebrum.Direct3D.Forms.ImageButton control = sender as Cerebrum.Direct3D.Forms.ImageButton;
			if(control != null && (control.Entered || control.Checked))
			{

				System.Drawing.Color clr = control.ForeColor;
				System.Drawing.Color clrb = control.ForeColor;

				ObjectiveDraw.Platform.GraphChartDevice dev = control.FindDevice() as ObjectiveDraw.Platform.GraphChartDevice;

				if(control.Checked)
				{
					clr = dev.ToolBarButtonCheckFillColor;
					clrb = dev.ToolBarButtonCheckRectColor;
				}
				else if(control.Pressed)
				{
					clr = dev.ToolBarButtonPressFillColor;
					clrb = dev.ToolBarButtonPressRectColor;
				}
				else if(control.Entered)
				{
					clr = dev.ToolBarButtonEnterFillColor;
					clrb = dev.ToolBarButtonEnterRectColor;
				}

				Cerebrum.Direct3D.Drawing.Graphics _Graphics = Cerebrum.Direct3D.Drawing.Graphics.FromDevice(e.Device);
				_Graphics.DrawRectangle(control.SurfaceRectangle, control.Z + control.Z * 0.02f, clr, control.Z + control.Z * 0.01f, clrb);
			}
		}	


		public static System.Drawing.Image DrawIntoBMP(System.Drawing.Image back, System.Drawing.Image icon, System.Drawing.PointF point, float a, bool shadow, System.Drawing.Point pointSH)
		{

			ImageAttributes imageAttributes =
				new ImageAttributes();

			/*ColorMap colorMap = new ColorMap();

			colorMap.OldColor=Color.FromArgb(255, 0, 255, 0);
			colorMap.NewColor=Color.FromArgb(0, 0, 0, 0);
			ColorMap[] remapTable = {colorMap};

			imageAttributes.SetRemapTable(remapTable,
				ColorAdjustType.Bitmap);*/

			float[][] colorMatrixElements = { 
												new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
												new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
												new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
												new float[] {0.0f,  0.0f,  0.0f,  a,    0.0f},
												new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
											};

			ColorMatrix wmColorMatrix = new
				ColorMatrix(colorMatrixElements);

			imageAttributes.SetColorMatrix(wmColorMatrix, 
				ColorMatrixFlag.Default, 
				ColorAdjustType.Bitmap);

			System.Drawing.Image target = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb);

			System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(target);

			g.Clear(System.Drawing.Color.Transparent);

			g.DrawImage(back, 
				new Rectangle(0,0,back.Height, back.Height),
				0, 0, back.Width, back.Height,		    
				GraphicsUnit.Pixel, 
				imageAttributes);

			if(shadow)
			{
				colorMatrixElements = new float[][] { 
														new float[] {0.8f,  0.1f,  0.1f,  0.0f, 0.0f},
														new float[] {0.1f,  0.8f,  0.1f,  0.0f, 0.0f},
														new float[] {0.1f,  0.1f,  0.8f,  0.0f, 0.0f},
														new float[] {0.0f,  0.0f,  0.0f,  0.5f, 0.0f},
														new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
													};
				wmColorMatrix = new
					ColorMatrix(colorMatrixElements);

				imageAttributes.SetColorMatrix(wmColorMatrix, 
					ColorMatrixFlag.Default, 
					ColorAdjustType.Bitmap);
			
				if(icon!=null)
					g.DrawImage(icon, 
						new Rectangle(pointSH.X, pointSH.Y, icon.Height, icon.Height),
						0, 0, icon.Width, icon.Height,		    
						GraphicsUnit.Pixel, 
						imageAttributes);

			}
			if(icon!=null)
				g.DrawImage(icon, point);

			g.Dispose();

			return target;
		}

		public static void InitImageButton(Cerebrum.Direct3D.Forms.ImageButton button, ObjectiveDraw.Platform.Application _app, System.Drawing.Image nimage, System.Drawing.Image limage, bool tristate)
		{
			System.Drawing.Color clr;
			clr = Color.White;

			System.Drawing.Image back;
			back = _app.UIButtonNormalLeaveBackImage;
			if(back!=null)
			{
				button.NormalLeaveImage = DrawIntoBMP(back, nimage, new System.Drawing.PointF(4, 4), 1, false, System.Drawing.Point.Empty); 
			}
			back = _app.UIButtonNormalEnterBackImage;
			if(back!=null)
			{
				
				button.NormalEnterImage = DrawIntoBMP(back, limage!=null?limage:nimage, new System.Drawing.PointF(3, 3), 1, true, new System.Drawing.Point(5, 5));
			}
			back = _app.UIButtonNormalPressBackImage;
			if(back!=null)
			{
				button.NormalPressImage = DrawIntoBMP(back, limage!=null?limage:nimage, new System.Drawing.PointF(5, 5), 1, false, System.Drawing.Point.Empty);
			}
			if(tristate)
			{
				back = _app.UIButtonCheckedLeaveBackImage;
				if(back!=null)
				{
				
					button.CheckedLeaveImage = DrawIntoBMP(back, nimage, new System.Drawing.PointF(4, 4), 1, false, System.Drawing.Point.Empty);
				}
				back = _app.UIButtonCheckedEnterBackImage;
				if(back!=null)
				{
				
					button.CheckedEnterImage = DrawIntoBMP(back, limage!=null?limage:nimage, new System.Drawing.PointF(3, 3), 1, true, new System.Drawing.Point(5, 5));
				}
				back = _app.UIButtonCheckedPressBackImage;
				if(back!=null)
				{
				
					button.CheckedPressImage = DrawIntoBMP(back, limage!=null?limage:nimage, new System.Drawing.PointF(5, 5), 1, false, System.Drawing.Point.Empty);
				}
			}
		}
	}
	public class DrawerBarDrawHelper
	{
		private DrawerBarDrawHelper()
		{
		}
		/*
				public static void DrawBars3D_old_new(IDrawerItemSource server, DrawerBarDrawerBase BarDrawer, DrawerChartContext context, float z, bool leftAllign, bool autoOrdinateScale)
				{
					CoordinatePosition AbscissaPosition = context.AbscissaPosition;
					CoordinatePosition CoordinatePosition = context.OrdinatePosition;
					ReferenceTimeStride timeBase = context.TimeBase as ReferenceTimeStride;

					float tleft = AbscissaPosition.Offset;
					double tsc = AbscissaPosition.Scale;
					float twidth = AbscissaPosition.Aperture;

					DateTimeRange m_TimeApertureRange = context.GetTimeApertureRange();

					DateTimeRange _barsRange = new DateTimeRange(m_TimeApertureRange.DateTime - timeBase.Stride, m_TimeApertureRange.TimeSpan + timeBase.Stride + timeBase.Stride);

					DrawerPosition []m_DrawerPositions = null;

					if(autoOrdinateScale)
					{
						float vmin, vmax;
						m_DrawerPositions = server.GetPositions(_barsRange, out vmin, out vmax);
						CoordinatePosition.Value = (vmax + vmin) / 2;
						CoordinatePosition.Scale = (double)CoordinatePosition.Aperture / (double)(vmax - vmin);
					}
					else
					{
						m_DrawerPositions = server.GetPositions(_barsRange);
					}


					System.DateTime tmin = m_TimeApertureRange.DateTime;
					System.DateTime tmax = m_TimeApertureRange.DateTime + m_TimeApertureRange.TimeSpan;

					double vsc = CoordinatePosition.Scale;
					float vpos = CoordinatePosition.Value;
					float vtop = CoordinatePosition.Offset;
					float vheight = CoordinatePosition.Aperture;

					_view _view = BarDrawer.Device._view;

					float ypos = vheight / 2 + vtop;

					foreach(DrawerPosition pos in m_DrawerPositions)
					{
						if(pos!=null)
						{
							float x0;
							float x1;
							if(leftAllign)
							{
								x0 = tleft + (float)((pos.OpenTime - tmin).TotalSeconds * tsc);
								x1 = tleft + (float)((pos.CloseTime - tmin).TotalSeconds * tsc);
							}
							else
							{
								x0 = tleft + twidth - (float)((tmax - pos.OpenTime).TotalSeconds * tsc);
								x1 = tleft + twidth - (float)((tmax - pos.CloseTime).TotalSeconds * tsc);
							}

							float min = ypos + (float)((vpos - pos.MinOrdinate) * vsc);
							float y0 = ypos + (float)((vpos - pos.OpenOrdinate) * vsc);
							float y1 = ypos + (float)((vpos - pos.CloseOrdinate) * vsc);
							float max = ypos + (float)((vpos - pos.MaxOrdinate) * vsc);
							if( (x1 >= _view.X || x0 <=  _view.X + _view.Width) && (min >= _view.Y || max <= _view.Y + _view.Width))
							{
								BarDrawer.DrawBar(min, y0, y1, max, x0 + 0.25f, x1 - 0.25f, z, !(pos.OpenOrdinate > pos.CloseOrdinate));
							}
						}
					}
				}
		*/
		/*		public static void DrawBars3D_old_old(PositionServer server, DrawerBarDrawerBase BarDrawer, CoordinatePosition AbscissaPosition, CoordinatePosition CoordinatePosition, System.DateTime timeBegin, System.TimeSpan timeStride, float z, bool leftAllign)
				{
					System.TimeSpan tstep = timeStride;
					double tsc = AbscissaPosition.Scale;
					float tleft = AbscissaPosition.Offset;
					float twidth = AbscissaPosition.Aperture;

					double vsc = CoordinatePosition.Scale;
					float vpos = CoordinatePosition.Value;
					float vtop = CoordinatePosition.Offset;
					float vheight = CoordinatePosition.Aperture;

					_view _view = BarDrawer.Device._view;

					float ypos = vheight / 2 + vtop;

					bool nega = timeBegin > AbscissaPosition.Value;

					System.DateTime tmax;
					System.DateTime tmin;

					if(nega)
					{
						tmax = timeBegin;
						tmin = AbscissaPosition.Value;
					}
					else
					{
						tmax = AbscissaPosition.Value;
						tmin = timeBegin;
					}

					System.DateTime tmpx = tmax - System.TimeSpan.FromSeconds(twidth / tsc);
					if(tmpx > tmin) tmin = tmpx;

					System.DateTime tcurr = timeBegin;
					System.DateTime tnext;

					System.DateTime tmax2 = tmax + tstep;
					System.DateTime tmin2 = tmin - tstep;

					while((tcurr < AbscissaPosition.Value && !nega) || (AbscissaPosition.Value < tcurr && nega))
					{
						if(nega)
						{
							tnext = tcurr - tstep;
						}
						else
						{
							tnext = tcurr + tstep;
						}

						if(tmin2 <= tcurr && tcurr <= tmax2)
						{
							DrawerPosition pos = null;
							if(nega)
							{
								pos = server.GetDrawerPosition(tnext, tstep);
							}
							else
							{
								pos = server.GetDrawerPosition(tcurr, tstep);
							}

					
							if(pos!=null)
							{
								float x0;
								float x1;
								if(leftAllign)
								{
									x0 = tleft + (float)((pos.OpenTime - tmin).TotalSeconds * tsc);
									x1 = tleft + (float)((pos.CloseTime - tmin).TotalSeconds * tsc);
								}
								else
								{
									x0 = tleft + twidth - (float)((tmax - pos.OpenTime).TotalSeconds * tsc);
									x1 = tleft + twidth - (float)((tmax - pos.CloseTime).TotalSeconds * tsc);
								}

								float min = ypos + (float)((vpos - pos.MinOrdinate) * vsc);
								float y0 = ypos + (float)((vpos - pos.OpenOrdinate) * vsc);
								float y1 = ypos + (float)((vpos - pos.CloseOrdinate) * vsc);
								float max = ypos + (float)((vpos - pos.MaxOrdinate) * vsc);
								if( (x1 >= _view.X || x0 <=  _view.X + _view.Width) && (min >= _view.Y || max <= _view.Y + _view.Width))
								{
									BarDrawer.DrawBar(min, y0, y1, max, x0 + 0.25f, x1 - 0.25f, z, (pos.OpenOrdinate < pos.CloseOrdinate));
								}
							}
						}

						tcurr = tnext;
					}
				}*/


		public static void DrawVRuller(Device device, System.Drawing.RectangleF _view, Cerebrum.Direct3D.Drawing.Font drawingFont, CoordinatePosition CoordinatePosition, float width, float z, bool leftAllign, DrawerChartBase chart)
		{
			double vsc = CoordinatePosition.Scale;
			float vpos = CoordinatePosition.Value;
			float vtop = CoordinatePosition.Offset;
			float vheight = CoordinatePosition.Aperture;

			double vampR = (Math.Min(_view.Y + _view.Height, CoordinatePosition.Offset + CoordinatePosition.Aperture) - Math.Max(_view.Y, CoordinatePosition.Offset) ) / vsc ; //_view.Height / vsc ;
			double vampG = vheight / vsc ;
			/*int vlog = (int)Math.Floor(Math.Log10(vampR)) - 1;

			double vst = Math.Pow(10, vlog);
	*/
			if(vsc <= 0 ) return;

			double vlog = Math.Log10(10.0 / vsc);
			int itr = 0;
			if(vlog < 0)
			{
				itr = (int)(Math.Floor(vlog - 0.5f));
			}
			else
			{
				itr = (int)(Math.Floor(vlog + 0.5f) + 0.5f);
			}

			double vst = Math.Pow(10, itr);

			if(vst * vsc < 4)
			{
				while(vst * vsc < 4)
				{
					vst *= 10;
				}
				if(vst * vsc > 24)
					vst /= 5;
			}

			int n = (int) (vampR / vst);

			if (n<1) return;

			int clr1 = chart.RulerOrdinateTenColor.ToArgb();
			int clr2 = chart.RulerOrdinateFiveColor.ToArgb();
			int clr3 = chart.RulerOrdinateOneColor.ToArgb();
			System.Drawing.Color clr4 = chart.RulerOrdinateTextColor;

			VertexBuffer VertexBuffer = new VertexBuffer(typeof(CustomVertex.TransformedColored), n * 2, device, Usage.WriteOnly, CustomVertex.TransformedColored.Format, Pool.Default);

			CustomVertex.TransformedColored[] verts = (CustomVertex.TransformedColored[])VertexBuffer.Lock(0,0); // Lock the buffer (which will return our structs)

			int clr;

			float v = (float)(vpos /*- vampG / 2*/ + (vtop + vheight / 2 - _view.Y - _view.Height) / vsc);
			v = (float)vst * ((int)Math.Floor(v / vst) + 1);

			int k = (int)Math.Floor((v - vst * 10 * (int)Math.Floor(v / vst / 10)) / vst + 0.5);

			float v2 = (float)(vpos + vampG / 2);
			for(int i=0; i<n; i++)
			{
				float y = (float)(vtop + (v2 - v) * vsc);

				verts[i*2].Position = new Vector4(_view.X, y, z, 1.0f);

				float w;
				if(k == 10)
				{
					k = 0;
					w = width * 2;

					Rectangle _rect = new Rectangle((int)(_view.X + w + 3), (int)(y - 5), 0 , 0);
					clr = clr1;

					drawingFont.DrawText(v.ToString("#,##0.00"), _rect, z, Microsoft.DirectX.Direct3D.DrawTextFormat.Left, clr4);
				}
				else if(k == 5)
				{
					w = width * 1.5f;
					clr = clr2;
				}
				else
				{
					w = width;
					clr = clr3;
				}
				verts[i*2 + 1].Position = new Vector4(_view.X + w, y, z, 1.0f);
				
				verts[i*2].Color = clr;
				verts[i*2 + 1].Color = clr;

				v+=(float)vst;
				k ++;
			}

			VertexBuffer.Unlock();

			device.VertexFormat = CustomVertex.TransformedColored.Format;

			// set the vertexbuffer stream source
			device.SetStreamSource(0, VertexBuffer, 0, VertexInformation.GetFormatSize(CustomVertex.TransformedColored.Format));
			// set fill mode
			device.RenderState.FillMode = FillMode.Solid;

			//use the indices buffer
			device.DrawPrimitives(PrimitiveType.LineList, 0, n);

			VertexBuffer.Dispose();
		}

		public static void DrawVLevels(Device device, System.Drawing.RectangleF _view, CoordinatePosition CoordinatePosition, float z, bool leftAllign, DrawerChartBase chart)
		{
			double vsc = CoordinatePosition.Scale;
			float vpos = CoordinatePosition.Value;
			float vtop = CoordinatePosition.Offset;
			float vheight = CoordinatePosition.Aperture;

			double vampR = (Math.Min(_view.Y + _view.Height, CoordinatePosition.Offset + CoordinatePosition.Aperture) - Math.Max(_view.Y, CoordinatePosition.Offset) ) / vsc ; //_view.Height / vsc ;
			double vampG = vheight / vsc ;
			/*int vlog = (int)Math.Floor(Math.Log10(vampR)) - 1;

			double vst = Math.Pow(10, vlog);
	*/
			if(vsc <= 0 ) return;

			double vlog = Math.Log10(10.0 / vsc);
			int itr = 0;
			if(vlog < 0)
			{
				itr = (int)(Math.Floor(vlog - 0.5f));
			}
			else
			{
				itr = (int)(Math.Floor(vlog + 0.5f) + 0.5f);
			}

			double vst = Math.Pow(10, itr);

			if(vst * vsc < 4)
			{
				while(vst * vsc < 4)
				{
					vst *= 10;
				}
				if(vst * vsc > 24)
					vst /= 5;
			}

			int n = (int) (vampR / vst);

			if (n<1) return;

			int clr1 = chart.ChartOrdinateTenColor.ToArgb();
		int clr2 = chart.ChartOrdinateFiveColor.ToArgb();
	int clr3 = chart.ChartOrdinateOneColor.ToArgb();

			VertexBuffer VertexBuffer = new VertexBuffer(typeof(CustomVertex.TransformedColored), n * 2, device, Usage.WriteOnly, CustomVertex.TransformedColored.Format, Pool.Default);

			CustomVertex.TransformedColored[] verts = (CustomVertex.TransformedColored[])VertexBuffer.Lock(0,0); // Lock the buffer (which will return our structs)

			int clr;

			float v = (float)(vpos /*- vampG / 2*/ + (vtop + vheight / 2 - _view.Y - _view.Height) / vsc);
			v = (float)vst * ((int)Math.Floor(v / vst) + 1);

			int k = (int)Math.Floor((v - vst * 10 * (int)Math.Floor(v / vst / 10)) / vst + 0.5);

			float v2 = (float)(vpos + vampG / 2);
			for(int i=0; i<n; i++)
			{
				if(k == 10)
				{
					k = 0;
					clr = clr1;
				}
				else if(k == 5)
				{
					clr = clr2;
				}
				else
				{
					clr = clr3;
				}

				float y = (float)(vtop + (v2 - v) * vsc);

				verts[i*2].Position = new Vector4(_view.X, y, z, 1.0f);
				verts[i*2].Color = clr;

				verts[i*2 + 1].Position = new Vector4(_view.X + _view.Width, y, z, 1.0f);
				verts[i*2 + 1].Color = clr;
				
				v+=(float)vst;
				k ++;
			}

			VertexBuffer.Unlock();

			device.VertexFormat = CustomVertex.TransformedColored.Format;

			// set the vertexbuffer stream source
			device.SetStreamSource(0, VertexBuffer, 0, VertexInformation.GetFormatSize(CustomVertex.TransformedColored.Format));
			// set fill mode
			device.RenderState.FillMode = FillMode.Solid;

			//use the indices buffer
			device.DrawPrimitives(PrimitiveType.LineList, 0, n);

			VertexBuffer.Dispose();
		}
		public static void DrawHRuller(Device device, System.Drawing.RectangleF _view, Cerebrum.Direct3D.Drawing.Font drawingFont, CoordinatePosition CoordinatePosition, float height, float z, bool leftAllign, GraphChartDevice chart)
		{
			double hsc = CoordinatePosition.Scale;
			float hpos = CoordinatePosition.Value;
			float htop = CoordinatePosition.Offset;
			float hwidth = CoordinatePosition.Aperture;

			double hampR = (Math.Min(_view.X + _view.Width, CoordinatePosition.Offset + CoordinatePosition.Aperture) - Math.Max(_view.X, CoordinatePosition.Offset) ) / hsc ; //_view.Height / hsc ;
			double hampG = hwidth / hsc ;
			/*int hlog = (int)Math.Floor(Math.Log10(hampR)) - 1;

			double hst = Math.Pow(10, hlog);
	*/
			if(hsc <= 0 ) return;

			double hlog = Math.Log10(10.0 / hsc);
			int itr = 0;
			if(hlog < 0)
			{
				itr = (int)(Math.Floor(hlog - 0.5f));
			}
			else
			{
				itr = (int)(Math.Floor(hlog + 0.5f) + 0.5f);
			}

			double hst = Math.Pow(10, itr);

			if(hst * hsc < 4)
			{
				while(hst * hsc < 4)
				{
					hst *= 10;
				}
				if(hst * hsc > 24)
					hst /= 5;
			}

			int n = (int) (hampR / hst);

			if (n<1) return;

			int clr1 = chart.RulerHorizontalDatumColor.ToArgb();
			int clr2 = chart.RulerHorizontalStrideColor.ToArgb();//chart.RulerOrdinateFiveColor.ToArgb();
			int clr3 = chart.RulerHorizontalStrideColor.ToArgb();
			System.Drawing.Color clr4 = chart.RulerHorizontalTextColor;

			VertexBuffer VertexBuffer = new VertexBuffer(typeof(CustomVertex.TransformedColored), n * 2, device, Usage.WriteOnly, CustomVertex.TransformedColored.Format, Pool.Default);

			CustomVertex.TransformedColored[] verts = (CustomVertex.TransformedColored[])VertexBuffer.Lock(0,0); // Lock the buffer (which will return our structs)

			int clr;

			float v = (float)(hpos /*- hampG / 2*/ - (htop + hwidth / 2 - _view.X) / hsc);
			v = (float)hst * ((int)Math.Floor(v / hst) + 1);

			int k = (int)Math.Floor((v - hst * 10 * (int)Math.Floor(v / hst / 10)) / hst + 0.5);

			float v2 = (float)(hpos - hampG / 2);
			for(int i=0; i<n; i++)
			{
				float x = (float)(htop + (v - v2) * hsc);

				verts[i*2].Position = new Vector4(x, _view.Y, z, 1.0f);

				float w;
				if(k == 10)
				{
					k = 0;
					w = height * 2;

					Rectangle _rect = new Rectangle((int)(x - 5), (int)(_view.Y + w + 3), 0 , 0);
					clr = clr1;

					drawingFont.DrawText(v.ToString("#,##0.00"), _rect, z, Microsoft.DirectX.Direct3D.DrawTextFormat.Left, clr4);
				}
				else if(k == 5)
				{
					w = height * 1.5f;
					clr = clr2;
				}
				else
				{
					w = height;
					clr = clr3;
				}
				verts[i*2 + 1].Position = new Vector4(x, _view.Y + w, z, 1.0f);
				
				verts[i*2].Color = clr;
				verts[i*2 + 1].Color = clr;

				v+=(float)hst;
				k ++;
			}

			VertexBuffer.Unlock();

			device.VertexFormat = CustomVertex.TransformedColored.Format;

			// set the vertexbuffer stream source
			device.SetStreamSource(0, VertexBuffer, 0, VertexInformation.GetFormatSize(CustomVertex.TransformedColored.Format));
			// set fill mode
			device.RenderState.FillMode = FillMode.Solid;

			//use the indices buffer
			device.DrawPrimitives(PrimitiveType.LineList, 0, n);

			VertexBuffer.Dispose();
		}


		public static void DrawHLevels(Device device, System.Drawing.RectangleF _view, CoordinatePosition CoordinatePosition, float z, bool leftAllign, DrawerChartBase chart)
		{
			double hsc = CoordinatePosition.Scale;
			float hpos = CoordinatePosition.Value;
			float htop = CoordinatePosition.Offset;
			float hwidth = CoordinatePosition.Aperture;

			double hampR = (Math.Min(_view.X + _view.Width, CoordinatePosition.Offset + CoordinatePosition.Aperture) - Math.Max(_view.X, CoordinatePosition.Offset) ) / hsc ; //_view.Height / hsc ;
			double hampG = hwidth / hsc ;
			/*int hlog = (int)Math.Floor(Math.Log10(hampR)) - 1;

			double hst = Math.Pow(10, hlog);
	*/
			if(hsc <= 0 ) return;

			double hlog = Math.Log10(10.0 / hsc);
			int itr = 0;
			if(hlog < 0)
			{
				itr = (int)(Math.Floor(hlog - 0.5f));
			}
			else
			{
				itr = (int)(Math.Floor(hlog + 0.5f) + 0.5f);
			}

			double hst = Math.Pow(10, itr);

			if(hst * hsc < 4)
			{
				while(hst * hsc < 4)
				{
					hst *= 10;
				}
				if(hst * hsc > 24)
					hst /= 5;
			}

			int n = (int) (hampR / hst);

			if (n<1) return;

			int clr1 = chart.ChartOrdinateTenColor.ToArgb();
			int clr2 = chart.ChartOrdinateFiveColor.ToArgb();
			int clr3 = chart.ChartOrdinateOneColor.ToArgb();

			VertexBuffer VertexBuffer = new VertexBuffer(typeof(CustomVertex.TransformedColored), n * 2, device, Usage.WriteOnly, CustomVertex.TransformedColored.Format, Pool.Default);

			CustomVertex.TransformedColored[] verts = (CustomVertex.TransformedColored[])VertexBuffer.Lock(0,0); // Lock the buffer (which will return our structs)

			int clr;

			float v = (float)(hpos /*- hampG / 2*/ - (htop + hwidth / 2 - _view.X) / hsc);
			v = (float)hst * ((int)Math.Floor(v / hst) + 1);

			int k = (int)Math.Floor((v - hst * 10 * (int)Math.Floor(v / hst / 10)) / hst + 0.5);

			float v2 = (float)(hpos - hampG / 2);
			for(int i=0; i<n; i++)
			{
				if(k == 10)
				{
					k = 0;
					clr = clr1;
				}
				else if(k == 5)
				{
					clr = clr2;
				}
				else
				{
					clr = clr3;
				}

				float x = (float)(htop + (v - v2) * hsc);

				verts[i*2].Position = new Vector4(x, _view.Y, z, 1.0f);
				verts[i*2].Color = clr;

				verts[i*2 + 1].Position = new Vector4(x, _view.Y + _view.Height, z, 1.0f);
				verts[i*2 + 1].Color = clr;
				
				v+=(float)hst;
				k ++;
			}

			VertexBuffer.Unlock();

			device.VertexFormat = CustomVertex.TransformedColored.Format;

			// set the vertexbuffer stream source
			device.SetStreamSource(0, VertexBuffer, 0, VertexInformation.GetFormatSize(CustomVertex.TransformedColored.Format));
			// set fill mode
			device.RenderState.FillMode = FillMode.Solid;

			//use the indices buffer
			device.DrawPrimitives(PrimitiveType.LineList, 0, n);

			VertexBuffer.Dispose();
		}

	}
}
